﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace LPBToolsLib
{
    public class BaseLib
    {

        #region 结构体与字节数组互转
        //结构体转字节数组     
        public static byte[] StructToBytes(object structObj)
        {

            int size = Marshal.SizeOf(structObj);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr(structObj, buffer, false);
                byte[] bytes = new byte[size];
                Marshal.Copy(buffer, bytes, 0, size);
                return bytes;
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }
        //字节数组转结构体     
        public static object BytesToStruct(byte[] bytes, Type strcutType)
        {
            int size = Marshal.SizeOf(strcutType);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(bytes, 0, buffer, size);
                return Marshal.PtrToStructure(buffer, strcutType);
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }
        #endregion

        #region 基础函数
        /// <summary>
        /// 检查电子邮件地址是否符合要求
        /// </summary>
        /// <param name="fEmail"></param>
        /// <returns></returns>
        public static bool checkEmailFormat(string fEmail)
        {
            return Regex.IsMatch(fEmail, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)" + @"|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }

        /// <summary>
        /// 从GUID生产16位长度的短ID
        /// 根据GUID生成16位的唯一ID
        /// </summary>
        /// <param name="NewGUID"></param>
        /// <returns></returns>
        public static string GUID16(Guid NewGUID)
        {
            long i = 1;
            foreach (byte b in NewGUID.ToByteArray())
            {
                i *= ((int)b + 1);
            }
            return string.Format("{0:x}", i - DateTime.Now.Ticks);
        }

        public static string GUID16()
        {
            string sResult = DateTime.Now.ToString("ssfff") + GUID16(Guid.NewGuid());
            return sResult.Substring(sResult.Length - 16, 16);
        }

        //如果你想生成一个数字序列而不是字符串，你将会获得一个19位长的序列。下面的方法会把GUID转换为Int64的数字序列。
        public static long GenerateIntID(Guid fNewGUID)
        {
            byte[] buffer = fNewGUID.ToByteArray();
            return BitConverter.ToInt64(buffer, 0);
        }

        #endregion

        #region 格式转换
        /// <summary>
        /// 将整数转换为Hex字符串
        /// </summary>
        /// <param name="Value">等待转换的整数</param>
        /// <param name="StrLen">输出最小长度，默认0为不限长度</param>
        /// <returns></returns>
        public static string IntToHex(int Value, int StrLen = 0)
        {
            string sResult = Convert.ToString(Value, 16);
            if (StrLen > 0)
                while (sResult.Length < StrLen)
                    sResult = "0" + sResult;
            return "0x" + sResult;
        }

        #endregion
    }
    public class BaseTools
    {

        /// <summary>
        /// 检验输入的字符串是否能够按照JSON格式成功转换为Dictionary<string, object>对象
        /// 测试过程中出现错误，无法解决，可能是使用了Core框架原因
        /// </summary>
        /// <param name="sInfo"></param>
        /// <returns></returns>
        public static bool isJSONStr<T>(string sInfo, out T tResult) where T: class
        {
            tResult = null;

            try
            {
                tResult = JsonConvert.DeserializeObject<T>(sInfo);
                return tResult != null;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
        /// 检查目标端口是否正在使用
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        public static bool PortInUse(int port)
        {
            bool inUse = false;

            IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
            IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();

            foreach (IPEndPoint endPoint in ipEndPoints)
            {
                if (endPoint.Port == port)
                {
                    inUse = true;
                    break;
                }
            }
            return inUse;  // 返回true说明端口被占用
        }


        /// <summary>
        /// 通过Ping检查目标IP地址是否有效
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool PingTest(string ip)
        {
            Ping p = new Ping();
            //PingOptions options = new PingOptions();
            //options.DontFragment = true;
            //string data = "Test Data!";
            //byte[] buffer = Encoding.ASCII.GetBytes(data);
            int timeout = 3000; // Timeout 时间，单位：毫秒
            //PingReply reply = p.Send(ip, timeout); // , buffer, options
            //Console.Write(reply.ToString());
            return (p.Send(ip, timeout).Status == IPStatus.Success);
        }

        public static string BytesToStrHex(byte[] tDatas)
        {
            string sTmp = "";
            if ((tDatas != null) && (tDatas.Length > 0))
                foreach (byte iValue in tDatas)
                    sTmp += string.Format("{0:X2} ", iValue);
            return sTmp.Trim();
        }

        public static string BytesToStrHex(ushort[] tDatas, int iSize)
        {
            string sTmp = "";
            if ((tDatas != null) && (tDatas.Length > 0)
                && (iSize > 0) && (iSize <= 8))
                foreach (short iValue in tDatas)
                    sTmp += string.Format("{0:X" + iSize.ToString() + "} ", iValue);
            return sTmp.Trim();
        }

        public static string BytesToStrHex(int[] tDatas, int iSize)
        {
            string sTmp = "";
            if ((tDatas != null) && (tDatas.Length > 0)
                && (iSize > 0) && (iSize <= 8))
                foreach (short iValue in tDatas)
                    sTmp += string.Format("{0:X" + iSize.ToString() + "} ", iValue);
            return sTmp.Trim();
        }

        /// <summary>
        /// 将代表16进制数的字符串转换为整数
        /// </summary>
        /// <param name="sHexStr">代表16进制数的字符串</param>
        /// <param name="tDatas">返回整数列表</param>
        /// <param name="sSplit">分割符，默认没有分割符</param>
        /// <returns></returns>
        public static int StrHexToInts(string sHexStr, out int[] tDatas, string sSplit = "")
        {
            tDatas = null;
            List<int> tResult = new List<int>();
            if (!string.IsNullOrEmpty(sHexStr))
            {
                List<string> tStrList = new List<string>();
                if (string.IsNullOrEmpty(sSplit))
                {
                    string sTmp = "";
                    for (int i = 0; i < sHexStr.Length; i++)
                        if (i % 2 == 0)
                        {
                            sTmp += sHexStr.ToArray()[i];
                        }
                        else
                        {
                            sTmp += sHexStr.ToArray()[i];
                            tStrList.Add(sTmp);
                            sTmp = "";
                        }
                }
                else
                {
                    sHexStr = sHexStr.Replace(sSplit, "-");
                    tStrList = new List<string>(sHexStr.Split('-'));
                }
                int iValue = 0;
                if ((tStrList != null) && (tStrList.Count > 0))
                {
                    foreach (string sV in tStrList)
                        if (int.TryParse(sV.Trim(), NumberStyles.AllowHexSpecifier, null, out iValue))
                        {
                            tResult.Add(iValue);
                        }
                        else
                        {
                            tResult.Clear();
                            break;
                        }
                    tDatas = tResult.ToArray();
                }
            }
            return tResult.Count;
        }

        /// <summary>
        /// 检查目标字符串是否符合IP地址要求
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <returns></returns>
        public static bool ValidateIPAddress(string ipAddress)
        {
            Regex validipregex = new Regex(@"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
            return ((!string.IsNullOrEmpty(ipAddress)) && validipregex.IsMatch(ipAddress.Trim())) ? true : false;
        }

        /// <summary>
        /// 提取输入字符串中，“_”后面的中文说明字符
        /// </summary>
        /// <param name="sSour"></param>
        /// <param name="sSplit"></param>
        /// <returns></returns>
        public static string getCNStrBySplit(string sSour, string sSplit = "_")
        {
            if ((!string.IsNullOrEmpty(sSour)) && (!string.IsNullOrEmpty(sSplit))
                && (sSour.IndexOf(sSplit) > 0)
                && (sSour.IndexOf(sSplit) + sSplit.Length < sSour.Length))
            {
                return sSour.Replace(sSour.Substring(0, sSour.IndexOf(sSplit) + sSplit.Length), string.Empty);
            }
            return sSour;
        }

    }
    public static class DTableToSerialize
    {
        /// <summary>
        /// 根据数据表内容，将数据表中数据，还原成泛型对象返回
        /// </summary>
        /// <typeparam name="T">对应数据表字段的对象</typeparam>
        /// <param name="TBDatas">输入的数据表</param>
        /// <param name="prefix">字段名称前缀</param>
        /// <param name="ignoreCase">忽略大小写</param>
        /// <returns></returns>
        public static List<T> GetList<T>(this DataTable TBDatas, string prefix = "", bool ignoreCase = true) where T : new()
        {
            if (TBDatas == null) return null;

            List<T> t = new List<T>();
            int columnscount = TBDatas.Columns.Count;
            if (ignoreCase)
            {
                for (int i = 0; i < columnscount; i++)
                    TBDatas.Columns[i].ColumnName = TBDatas.Columns[i].ColumnName.ToUpper();
            }
            var properties = new T().GetType().GetProperties();

            var rowscount = TBDatas.Rows.Count;
            for (int i = 0; i < rowscount; i++)
            {
                var model = new T();
                foreach (var p in properties)
                {
                    var keyName = prefix + p.Name + "";
                    if (ignoreCase)
                        keyName = keyName.ToUpper();
                    for (int j = 0; j < columnscount; j++)
                    {
                        if (TBDatas.Columns[j].ColumnName == keyName && TBDatas.Rows[i][j] != null)
                        {
                            string pval = TBDatas.Rows[i][j].ToString();
                            if (!string.IsNullOrEmpty(pval))
                            {
                                if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                                {
                                    p.SetValue(model, Convert.ChangeType(TBDatas.Rows[i][j], p.PropertyType.GetGenericArguments()[0]), null);
                                }
                                else
                                {
                                    p.SetValue(model, Convert.ChangeType(TBDatas.Rows[i][j], p.PropertyType), null);
                                }
                            }
                            break;
                        }
                    }
                }
                t.Add(model);
            }
            return t;
        }

        /// <summary>
        /// 获得提供的数据表的字段名称
        /// 仅获得数据表的字段信息，不包括数据
        /// </summary>
        /// <param name="tDatatable"></param>
        /// <returns></returns>
        static public List<string> getTableFieldNames(DataTable tDatatable, string BindFieldName = "")
        {
            List<string> tResult = new List<string>();
            if (tDatatable != null)
            {
                List<string> tBindFNList = new List<string>();
                if (!string.IsNullOrEmpty(BindFieldName))
                {
                    tBindFNList.AddRange(BindFieldName.Split(','));
                }
                foreach (DataColumn dColumn in tDatatable.Columns)
                    if (!tBindFNList.Contains(dColumn.ColumnName))
                        tResult.Add(dColumn.ColumnName);
            }
            return tResult;
        }

        /// <summary>
        /// 获得数据表中的数据
        /// 仅获得所有数据的阵列，没有任何字段名称表述
        /// </summary>
        /// <param name="tDatatable"></param>
        /// <returns></returns>
        static public List<object> getTableDatas(DataTable tDatatable, string BindFieldName = "")
        {
            List<object> tRows = new List<object>();

            if (tDatatable != null)
            {
                List<string> tBindFNList = new List<string>();
                if (!string.IsNullOrEmpty(BindFieldName))
                {
                    tBindFNList.AddRange(BindFieldName.Split(','));
                }
                for (int i = 0; i < tDatatable.Rows.Count; i++)
                {
                    List<object> tRowValues = new List<object>();
                    foreach (DataColumn dColumn in tDatatable.Columns)
                        if (!tBindFNList.Contains(dColumn.ColumnName))
                            tRowValues.Add(tDatatable.Rows[i][dColumn.ColumnName].ToString().Trim());
                    tRows.Add(tRowValues);
                }
            }
            return tRows;
        }

        /// <summary>
        /// 将数据表转换为可以序列化的字典
        /// 第一行为字段，后续为数据
        /// </summary>
        /// <param name="tDatatable"></param>
        /// <returns></returns>
        static public Dictionary<string, object> DataToDict(DataTable tDatatable, string BindFieldName = "")
        {
            Dictionary<string, object> tResult = null;
            if (tDatatable != null)
            {
                tResult = new Dictionary<string, object>();
                tResult.Add("Fields", getTableFieldNames(tDatatable, BindFieldName));
                tResult.Add("Datas", getTableDatas(tDatatable, BindFieldName));
            }
            return tResult;
        }
        /// <summary>
        /// 将数据表转换为可以序列化的字典
        /// 每行都是字典方式，字段名为Key
        /// </summary>
        /// <param name="tDatatable"></param>
        /// <param name="BindFieldName">不导入的字段列表，以‘，’分割，默认没有禁止字段</param>
        /// <returns></returns>
        static public List<object> DataToDictTiny(DataTable tDatatable, string BindFieldName = "")
        {
            List<object> tResult = null;
            List<string> tBindFNList = new List<string>();
            if (!string.IsNullOrEmpty(BindFieldName))
            {
                tBindFNList.AddRange(BindFieldName.Split(','));
            }
            if (tDatatable != null)
            {
                tResult = new List<object>();
                foreach (DataRow tRow in tDatatable.Rows)
                {
                    Dictionary<string, object> tRole = new Dictionary<string, object>();
                    for (int i = 0; i < tDatatable.Columns.Count; i++)
                        if ((!tRole.ContainsKey(tDatatable.Columns[i].ColumnName))
                            && (!tBindFNList.Contains(tDatatable.Columns[i].ColumnName)))
                            tRole.Add(tDatatable.Columns[i].ColumnName, tRow[i].ToString());
                    tResult.Add(tRole);
                }
            }
            return tResult;
        }

        static public List<Dictionary<string, object>> DataToDictEx(DataTable tDatatable, string BindFieldName = "")
        {
            List<Dictionary<string, object>> tResult = null;
            List<string> tBindFNList = new List<string>();
            if (!string.IsNullOrEmpty(BindFieldName))
            {
                tBindFNList.AddRange(BindFieldName.Split(','));
            }
            if (tDatatable != null)
            {
                tResult = new List<Dictionary<string, object>>();
                foreach (DataRow tRow in tDatatable.Rows)
                {
                    Dictionary<string, object> tRole = new Dictionary<string, object>();
                    for (int i = 0; i < tDatatable.Columns.Count; i++)
                        if ((!tRole.ContainsKey(tDatatable.Columns[i].ColumnName))
                            && (!tBindFNList.Contains(tDatatable.Columns[i].ColumnName)))
                            tRole.Add(tDatatable.Columns[i].ColumnName, tRow[i].ToString());
                    tResult.Add(tRole);
                }
            }
            return tResult;
        }
    }

    /// <summary>
    /// 需要Windows系统
    /// </summary>
    public class RichTextGoBottom
    {
        const int WM_VSCROLL = 0x0115;
        const int SB_BOTTOM = 7;

        [DllImport("user32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);

        /// <summary>
        /// 将目标多行文字对象的当前工作位置移动到底部
        /// </summary>
        /// <param name="RichTextBoxHandle">多行文字对象的句柄</param>
        public static void GoBottom(IntPtr RichTextBoxHandle)
        {
            if (RichTextBoxHandle != IntPtr.Zero)
                // 将显示位置移动到最后
                SendMessage(RichTextBoxHandle, WM_VSCROLL, SB_BOTTOM, 0);
        }

        /// <summary>
        /// 将目标多行文字对象的当前工作位置移动到底部
        /// </summary>
        /// <param name="fRichTextBox">多行文字对象</param>
        public static void GoBottom(RichTextBox fRichTextBox)
        {
            if (fRichTextBox != null)
                // 将显示位置移动到最后
                SendMessage(fRichTextBox.Handle, WM_VSCROLL, SB_BOTTOM, 0);
        }
    }

    /// <summary>
    /// 提取属性的Display名称
    /// demo：
    /// 获取FileInfo类中FileName属性的DisplayName
    /// string displayName = DisplayNameHelper.GetDisplayName(typeof(FileInfo), "FileName");
    /// displayName:输出：[DisplayName("文件名")]中信息：‘文件名’
    /// 
    /// 获取未标注DisplayName的属性（返回属性名）
    /// string filePathName = DisplayNameHelper.GetDisplayName(typeof(FileInfo), "FilePath");
    /// filePathName:输出：FilePath
    /// </summary>
    public class DisplayNameHelper
    {
        public static string GetDisplayName(Type type, string propertyName)
        {
            // 1. 获取属性的反射信息
            PropertyInfo property = type.GetProperty(propertyName);
            if (property == null)
            {
                throw new ArgumentException($"属性 {propertyName} 在类型 {type.Name} 中不存在");
            }

            // 2. 提取DisplayNameAttribute
            DisplayNameAttribute displayNameAttr = property.GetCustomAttribute<DisplayNameAttribute>();

            // 3. 返回结果（有特性则返回DisplayName，否则返回属性名）
            return displayNameAttr?.DisplayName ?? propertyName;
        }
    }

    #region (*运行中数据记录器 2023-04-23*)

    #region 抽象基础类
    /// <summary>
    /// 容器基础类
    /// 可以根据Public属性，直接生成属性内容细节
    /// </summary>
    public abstract class ContainerBase
    {
        public string toDetail()
        {
            string sResult = "";
            toDetail(out sResult);
            return sResult;
        }

        /// <summary>
        /// 根据模板结构，导出模板Public内容细节
        /// </summary>
        /// <param name="Detail">输出的属性名称及当前值</param>
        /// <returns></returns>
        public bool toDetail(out string Detail)
        {
            Detail = "";
            Dictionary<string, object> tBoardDetail = null;
            if (toDetail(out tBoardDetail)
                && (tBoardDetail != null))
            {
                Detail = JsonConvert.SerializeObject(tBoardDetail);
                return true;
            }
            return false;
        }

        public bool toDetail(out Dictionary<string, object> Detail)
        {
            Detail = null;
            PropertyInfo[] tPropList = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
            Detail = new Dictionary<string, object>();
            foreach (PropertyInfo tPropertyInfo in tPropList)
                Detail.Add(tPropertyInfo.Name, tPropertyInfo.GetValue(this, null));
            return true;
        }

        /// <summary>
        /// 根据模板结构，导出模板Public内容细节
        /// </summary>
        /// <param name="Detail">输出的Display名称及当前值</param>
        /// <returns></returns>
        public bool toDetailByDName(out Dictionary<string, object> Detail)
        {
            Detail = null;
            PropertyInfo[] tPropList = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
            Detail = new Dictionary<string, object>();
            foreach (PropertyInfo tPropertyInfo in tPropList)
            {
                var DisplayAttrib = tPropertyInfo.GetCustomAttribute<DisplayNameAttribute>();
                if ((DisplayAttrib != null)
                    && (!string.IsNullOrEmpty(DisplayAttrib.DisplayName)))
                    Detail.Add(DisplayAttrib.DisplayName, tPropertyInfo.GetValue(this, null));
                else
                    Detail.Add(tPropertyInfo.Name, tPropertyInfo.GetValue(this, null));
            }
            return true;
        }
    }

    /// <summary>
    /// 模板基础类型
    /// 可以根据类型中声明的Public属性，直接生成属性内容细节字符串
    /// 同时可以直接根据细节生成public属性的初始值
    /// </summary>
    public abstract class RecordBase : ContainerBase
    {
        public RecordBase(Dictionary<string, object> Detail) : this(JsonConvert.SerializeObject(Detail))
        {
        }
        public RecordBase(string Detail)
        {
            Dictionary<string, object> tBoardDetail = null;
            if ((!string.IsNullOrEmpty(Detail))
                && BaseTools.isJSONStr(Detail, out tBoardDetail))
                getValuesByDict(tBoardDetail);
        }
        /// <summary>
        /// 根据输入的细节值创建对象
        /// 仅根据输入的属性初始化，未输入的可以还是默认值，未设置为输入的将被忽略
        /// </summary>
        /// <param name="Detail"></param>
        protected void getValuesByDict(Dictionary<string, object> Detail)
        {
            if (Detail != null)
            {
                PropertyInfo[] tPropList = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

                foreach (KeyValuePair<string, object> Item in Detail)
                {
                    PropertyInfo tDestPInfo = GetType().GetProperty(Item.Key);
                    if ((tDestPInfo != null) && (tDestPInfo.SetMethod != null))
                    {
                        try
                        {
                            if (tDestPInfo.PropertyType.IsGenericType
                            && tDestPInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                            {
                                tDestPInfo.SetValue(this, Convert.ChangeType(Detail[tDestPInfo.Name], tDestPInfo.PropertyType.GetGenericArguments()[0]), null);
                            }
                            else
                            {
                                tDestPInfo.SetValue(this, Convert.ChangeType(Detail[tDestPInfo.Name], tDestPInfo.PropertyType), null);
                            }
                        }
                        //tDestPInfo.SetValue(this, Detail[tDestPInfo.Name]);}
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                    }
                }
            }
        }
    }

    /// <summary>
    /// 运行中数据记录基础类型，数据记录器
    /// </summary>
    public abstract class RecorderBase : ContainerBase
    {
        #region 私有、继承对象及属性
        private string MutexStr { get; } = "ZLRunRecordsBase-" + Guid.NewGuid().ToString("N");
        private Mutex tMutex { get; set; } = null;
        /// <summary>
        /// 运行数据
        /// </summary>
        private List<object> tDatas { get; set; } = new List<object>();
        private int iMaxBufSize { get; set; } = 100;
        protected T GetRecord<T>(int fIdx = 0)
        //where T : ISports//接口约束
        where T : class//引用类型约束
                       //where T : struct//值类型约束
                       // where T : new()//无参数构造函数约束
        {
            T fResult = null;
            if ((tDatas.Count > 0) && (tDatas.Count > fIdx) && (fIdx >= 0))
            {
                tMutex.WaitOne();
                try
                {
                    fResult = (T)tDatas[fIdx];
                    tDatas.RemoveAt(fIdx);
                }
                finally
                {
                    tMutex.ReleaseMutex();
                }
            }
            return fResult;
        }

        protected int SetRecord<T>(T Value)
        //where T : ISports//接口约束
        where T : class//引用类型约束
                       //where T : struct//值类型约束
                       // where T : new()//无参数构造函数约束
        {
            tMutex.WaitOne();
            try
            {
                tDatas.Add(Value);
                if (iMaxBufSize < tDatas.Count)
                    tDatas.RemoveAt(0);
            }
            finally
            {
                tMutex.ReleaseMutex();
            }
            return tDatas.Count();
        }
        /// <summary>
        /// 返回的数据组
        /// </summary>
        protected object[] Datas
        {
            get { return tDatas.ToArray(); }
            set
            {
                tMutex.WaitOne();
                try
                {
                    tDatas = new List<object>(value);
                }
                finally
                {
                    tMutex.ReleaseMutex();
                }
            }
        }
        #endregion

        #region 公开属性、方法及构建函数
        /// <summary>
        /// 创建时间
        /// </summary>
        //public DateTime DataTime { get; } = DateTime.Now;
        public int RecCount { get { return tDatas.Count; } }
        /// <summary>
        /// 缓冲区最大容量，避免过度占用内存
        /// </summary>
        public int MaxBufSize { get { return iMaxBufSize; } set { if (value >= 0) iMaxBufSize = value; } }

        public void Clear()
        {
            tMutex.WaitOne();
            try
            {
                tDatas.Clear();
            }
            finally
            {
                tMutex.ReleaseMutex();
            }
        }

        public RecorderBase()
        {
            tMutex = new Mutex(false, MutexStr);
        }
        #endregion
    }
    #endregion

    #region 记录信息
    public class Record : RecordBase
    {
        [DisplayName("创建时间")]
        public DateTime CreateTime { get; } = DateTime.Now;
        [DisplayName("信息内容")]
        public string Info { get; set; } = "";

        //public Record(string Detail) : base(Detail) { }
        public Record(string DestInfo):base("")
        {
            Info = DestInfo;
        }
        public string toLogStr()
        {
            return string.Format("[{0}]{1}",
                CreateTime.ToString("HH:mm:ss fff"),
                Info);
        }
    }

    public class Record_Byte : Record
    {
        [DisplayName("运行的数据信息")]
        public byte[] RunDatas { get; set; } = new byte[0];

        public Record_Byte(string DestInfo, byte[] DestDatas) : base("")
        {
            Info = DestInfo;
            RunDatas = DestDatas;
        }

        public string toLogStr()
        {
            return string.Format("[{0}]{1}:{2}",
                CreateTime.ToString("HH:mm:ss fff"),
                Info, BaseTools.BytesToStrHex(RunDatas));
        }
    }
    #endregion

    #region 数据记录器
    /// <summary>
    /// 运行日志记录器，仅记录字符串信息
    /// </summary>
    public class Recorder_RunLog : RecorderBase
    {
        public Record getRecord()
        {
            return base.GetRecord<Record>();
        }

        public int setRecord(Record value)
        {
            return base.SetRecord<Record>(value);
        }
    }

    /// <summary>
    /// 数据传输记录器，记录传输的二进制流
    /// </summary>
    public class Recorder_RTxBytes : RecorderBase
    {
        public Record_Byte getRecord()
        {
            return base.GetRecord<Record_Byte>();
        }

        public int setRecord(Record_Byte value)
        {
            return base.SetRecord<Record_Byte>(value);
        }
    }

    /// <summary>
    /// 系统错误记录器，用于没有前段界面，不便于查看错误的应用
    /// 增加了清理错误列表功能，该功能同时一次提取全部错误记录
    /// </summary>
    public class Recorder_Error : RecorderBase
    {
        public Exception getRecord()
        {
            return base.GetRecord<Exception>();
        }

        public int setRecord(Exception value)
        {
            return base.SetRecord<Exception>(value);
        }

        public Exception[] ClearAll()
        {
            object[] tTmp = base.Datas;
            List<Exception> tErrList = new List<Exception>();
            foreach (object item in tTmp)
                tErrList.Add((Exception)item);
            base.Clear();
            return tErrList.ToArray();
        }

        public Dictionary<string, object>[] getAllErrorStr()
        {
            Exception[] tmp = ClearAll();

            List<Dictionary<string, object>> tErrorList = new List<Dictionary<string, object>>();
            foreach (Exception ex in tmp)
            {
                Dictionary<string, object> tExInfo = new Dictionary<string, object>();
                tExInfo.Add("msg", ex.Message);
                tExInfo.Add("sour", ex.Source);
                if (ex.InnerException != null)
                    tExInfo.Add("iner", ex.InnerException.Message);
                tExInfo.Add("trace", ex.StackTrace);
                tErrorList.Add(tExInfo);
            }
            return tErrorList.ToArray();
        }
    }
    #endregion

    #endregion
}
